package com.gm.server.voice.core;


import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.gm.server.voice.core.runable.ReceiveAudio;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedHashMap;
import java.util.Map;

@Slf4j
@Component
public class ServerSocketCore {

    @Value("${config.socket.port}")
    private int serverPort;

    // 用一个Map储存房间信息，key为房间ID，value为房间对象
    private Map<String, VoiceRoom> roomMap = new LinkedHashMap<>();

    public void startServer() {
        try {
            // 启动serverSocket
            ServerSocket serverSocket = new ServerSocket(serverPort);
            log.info("服务器启动，等待客户端连接...");

            Socket socket = null;
            // 监听客户端连接
            while ((socket = serverSocket.accept()) != null) {
                log.info("客户端已连接: " + socket.getInetAddress());
                // 检测到客户端接入，将客户端信息存储到房间Map中
                // 读取客户端信息
                BufferedReader ticketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                StringBuilder response = new StringBuilder();
                String infoStr = null;
                while ((infoStr = ticketReader.readLine()) != null) {
                    response.append(infoStr);
                }
                // 这里需要先使用sm4对信息解密后在进行解析
                // 但是测试阶段，先不进行加密
                JSONObject responseJson = JSONObject.parseObject(response.toString());
                // 获取票据校验
                String ticket = responseJson.getString("ticket");
                // 这里模拟校验，实际上应该是需要进行更为复杂的校验
                if (ticket == null || "1".equals(ticket)) {
                    // 票据校验失败，关闭socket
                    socket.close();
                }
                // 获取操作类型
                String operationType = responseJson.getString("operationType");
                // 创建房间
                if ("cr_01".equals(operationType)) {
                    String userId = responseJson.getString("userId");
                    String roomId = "1"; // 从数据库中获取房间ID 或者 通过ip及mac信息生成房间号，这里测试设置为1
                    VoiceRoom room = new VoiceRoom(roomId);
                    if (StringUtils.isNotBlank(userId)) {
                        room.putUserSocket(userId, socket);
                        room.putReceiveAudio(userId, socket);
                    }
                    // 房间创建后即开启发送
                    room.startSendVoice();
                    roomMap.put(roomId, room);
                }
                // 加入房间
                else if ("jr_01".equals(operationType)) {
                    // 获取用户信息，并将 socket 存储到房间Map中
                    String roomId = responseJson.getString("roomId");
                    String userId = responseJson.getString("userId");
                    VoiceRoom room = roomMap.get(roomId);
                    if (room != null && StringUtils.isNotBlank(userId)) {
                        room.putUserSocket(userId, socket);
                        room.putReceiveAudio(userId, socket);
                    }
                } else {
                    log.info("未知操作类型");
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
